package com.buffer.agent.service;


import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.buffer.agent.tool.AgentTool;
import com.buffer.agent.memory.SessionMemory;
import com.buffer.agent.tool.ToolResult;
import com.buffer.agent.tool.ToolType;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

// 智能体核心服务：对话决策、工具调用、结果生成
@Service
public class QwenAgentService {
    
    @Resource
    private Generation qwenClient;
    
    @Resource
    private SessionMemory sessionMemory;
    
    // 自动注入所有实现AgentTool接口的Bean
    @Autowired
    private List<AgentTool> toolList;
    
    // 工具映射：按类型快速查找
    private Map<ToolType, AgentTool> toolMap;
    
    @Value("${dashscope.model}")
    private String qwenModel;
    
    // 项目启动完成后自动完成注册
    @PostConstruct
    public void init() {
        // 工具映射：按类型快速查找
        this.toolMap = toolList.stream()
                .collect(Collectors.toMap(AgentTool::getType, tool -> tool));
    }
    
    // 处理用户请求（核心方法）
    public String processRequest(String userId, String userQuery) throws NoApiKeyException, InputRequiredException {
        // 1. 获取对话历史（上下文）
        String history = sessionMemory.getHistory(userId);
        
        // 2. 构建提示词：指导智能体决策（是否调用工具）
        String systemPrompt = buildSystemPrompt(history);
        
        // 3. 调用通义千问，获取决策结果
        List<Message> messages = new ArrayList<>();
        messages.add(Message.builder()
                .role(Role.SYSTEM.getValue())
                .content(systemPrompt)
                .build());
        messages.add(Message.builder()
                .role(Role.USER.getValue())
                .content(userQuery)
                .build());
        
        // 构造请求参数
        GenerationParam param = GenerationParam.builder()
                .model(qwenModel)
                .messages(messages)
                .temperature(0.3f)  // 降低随机性，决策更稳定
                .resultFormat(GenerationParam.ResultFormat.MESSAGE)
                .build();
        
        // 调用大模型
        GenerationResult result = qwenClient.call(param);
        String modelResponse = result.getOutput().getChoices().get(0).getMessage().getContent();
        
        // 4. 解析决策：是否需要调用工具
        String finalResponse = parseModelDecision(modelResponse, userQuery);
        
        // 5. 保存对话历史
        sessionMemory.saveHistory(userId, userQuery, finalResponse);
        
        return finalResponse;
    }
    
    // 构建系统提示词（关键：指导智能体行为）
    private String buildSystemPrompt(String history) {
        StringBuilder prompt = new StringBuilder();
        prompt.append("你是一个智能助手，具备工具调用能力，规则如下：\n");
        prompt.append("1. 先查看对话历史：").append(history).append("\n");
        prompt.append("2. 可用工具：\n");
        for (ToolType type : ToolType.values()) {
            prompt.append("- ").append(type.getName()).append("：").append(type.getDescription()).append("\n");
        }
        prompt.append("3. 决策逻辑：\n");
        prompt.append("   - 不需要工具：直接用自然语言回答用户问题；\n");
        prompt.append("   - 需要工具：仅返回「工具类型:参数」格式（如 时间查询工具:无 或 文件读取工具:D:/test.txt），不添加其他内容；\n");
        prompt.append("4. 严格按照格式返回，不要额外解释。");
        return prompt.toString();
    }
    
    // 解析大模型决策，执行工具或直接返回结果
    private String parseModelDecision(String modelResponse, String userQuery) {
        // 遍历所有工具，判断是否需要调用
        for (ToolType toolType : ToolType.values()) {
            if (modelResponse.startsWith(toolType.getName() + ":")) {
                // 提取工具参数
                String param = modelResponse.split(":", 2)[1].trim();
                // 执行工具
                AgentTool tool = toolMap.get(toolType);
                ToolResult toolResult = tool.execute(param);
                return toolResult.isSuccess() ? toolResult.getResult() : "工具调用失败：" + toolResult.getResult();
            }
        }
        // 不需要工具，直接返回大模型回答
        return modelResponse;
    }
    
    // getter方法，用于获取toolMap
    public Map<ToolType, AgentTool> getToolMap() {
        return toolMap;
    }
}